package com.ruoyi.app.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import com.ruoyi.app.common.OrderNumUtil;
import com.ruoyi.app.common.jwt.TokenService;
import com.ruoyi.app.service.ChargeOrderService;
import com.ruoyi.common.ClientUtils;
import com.ruoyi.common.WxValueConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MqttLockUtil;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.app.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.mapper.app.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.ClientProtocolException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class ChargeOrderServiceImpl implements ChargeOrderService {

    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderChargeMapper orderChargeMapper;
    @Autowired
    OrderCardChargeMapper orderCardChargeMapper;
    @Autowired
    OrderComboMapper orderComboMapper;
    @Autowired
    TokenService tokenService;
    @Autowired
    ChargeOptionMapper chargeOptionMapper;
    @Autowired
    CardChargeOptionMapper cardChargeOptionMapper;
    @Autowired
    ComboMapper comboMapper;
    @Autowired
    CommunityMapper communityMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    CardMapper cardMapper;
    @Autowired
    WxValueConfig wxPledgeConfig;
    @Autowired
    CommunityMemberMapper communityMemberMapper;
    @Autowired
    DeviceMapper deviceMapper;
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    RechargeOrderMapper rechargeOrderMapper;
    @Autowired
    CommunityPartnerMapper communityPartnerMapper;
    @Autowired
    ParticipationMapper participationMapper;
    @Autowired
    DeviceSpaceMapper deviceSpaceMapper;
    @Autowired
    MqttLockUtil mqttLockUtil;
    @Autowired
    DeptWxInfoMapper deptWxInfoMapper;

    @Override
    public List<Order> chargeList() {
        User user = tokenService.getUser(ServletUtils.getRequest());
        return orderMapper.chargeList(user.getId());
    }

    @Override
    public AjaxResult getOrderInfo(Long id, Integer type) {
        if (type == 1) {
            return AjaxResult.success(orderChargeMapper.selectByPrimaryKey(id));
        } else if (type == 2) {
            return AjaxResult.success(orderComboMapper.selectByPrimaryKey(id));
        } else if (type == 3) {
            return AjaxResult.success(orderCardChargeMapper.selectByPrimaryKey(id));
        }
        return null;
    }

    @Override
    public List<RechargeOrder> rechargeList(Long orderId) {
        return rechargeOrderMapper.rechargeList(tokenService.getUser(ServletUtils.getRequest()).getId(), orderId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long createCardChargeOrder(Long communityId, Long optionId, String cardNum) {
        User user = userMapper.selectByPrimaryKey(tokenService.getUser(ServletUtils.getRequest()).getId());
        Card card = cardMapper.selectByNum(cardNum);
        if (StringUtils.isNull(card)) {
            throw new ServiceException("卡号不存在!");
        }
        if (StringUtils.isNull(card.getUserId()) || !card.getUserId().equals(user.getId())) {
            throw new ServiceException("电卡异常!");
        }
        if (card.getCardState() != 1) {
            throw new ServiceException("电卡禁用或挂失!");
        }
        if (StringUtils.isNull(card.getCommunityId()) || !communityId.equals(card.getCommunityId())) {
            throw new ServiceException("电卡小区不匹配！");
        }
        Order order = createOrder(communityId, 3);
        CardChargeOption chargeOption = cardChargeOptionMapper.selectByPrimaryKey(optionId);
        BigDecimal chargeMoney = chargeOption.getMoney();
        OrderCardCharge orderCardCharge = new OrderCardCharge();
        orderCardCharge.setChargeMoney(chargeMoney);
        orderCardCharge.setDiscountMoney(chargeOption.getDiscountsMoney());
        orderCardCharge.setCardNum(cardNum);
        orderCardCharge.setOrderId(order.getId());
        orderCardChargeMapper.insert(orderCardCharge);
        order.setMoney(chargeMoney);
        orderMapper.updateByPrimaryKeySelective(order);
        return order.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long createComboChargeOrder(Long communityId, Long optionId) {
        Order order = createOrder(communityId, 2);
        Combo combo = comboMapper.selectByPrimaryKey(optionId);
        BigDecimal chargeMoney = combo.getMoney();
        OrderCombo orderCombo = new OrderCombo();
        orderCombo.setOrderId(order.getId());
        orderCombo.setComboTime(combo.getByTime());
        orderComboMapper.insertSelective(orderCombo);
        order.setMoney(chargeMoney);
        orderMapper.updateByPrimaryKeySelective(order);
        return order.getId();
    }



    //@Transactional(rollbackFor = Exception.class)
    @Override
    public Long createRecharge(String deviceNum, Integer chargeTime, Integer socketNo) {
        User user = tokenService.getUser(ServletUtils.getRequest());

        if (user.getState() == 0) {
            throw new ServiceException("您已被禁用！");
        }
        Device device = deviceMapper.selectByNum(deviceNum);
        if (StringUtils.isNull(device)) {
            throw new ServiceException("设备不存在！");
        }
        if (device.getDeviceState() == 0) {
            throw new ServiceException("设备已禁用！");
        }
        if (device.getDeviceLineState() != 1) {
            throw new ServiceException("设备不在线！");
        }
        Community community = communityMapper.selectByPrimaryKey(device.getCommunityId());
        if (StringUtils.isNull(community)) {
            throw new ServiceException("设备未绑定小区");
        }
        if (community.getCommunityState() == 0) {
            throw new ServiceException("小区已被禁用!");
        }

        DeviceSpace deviceSpace = deviceSpaceMapper.selectBySpaceId(device.getId(), socketNo);
        if (deviceSpace.getState() != 0) {
            throw new ServiceException("插座忙碌中或故障");
        }

        SysUser sysUser = sysUserMapper.selectUserById(device.getOperatorId());
        if (StringUtils.isNull(sysUser)) {
            throw new ServiceException("设备未绑定运营商");
        }

        DeptWxInfo deptWxInfo = deptWxInfoMapper.selectByAppId(community.getAppId());
        if (deptWxInfo == null || !deptWxInfo.getAppId().equals(user.getAppId())) {
            throw new ServiceException("您无法在此设备充电！");
        }

        CommunityMember communityMember = communityMemberMapper.selectByUser(user.getId(), community.getId());
        if (StringUtils.isNull(communityMember) && community.getIsBalanceUse() == 0) {
            throw new ServiceException("用户在小区下未充值！请充值后再试");
        } else if (StringUtils.isNull(communityMember) && community.getIsBalanceUse() == 1) {
            BigDecimal allBalance = communityMemberMapper.getBalanceByOperatorId(user.getId(), community.getOperatorId());
            if (allBalance.doubleValue() <= 0D) {
                throw new ServiceException("用户在本运营商下未充值！请充值后再试");
            }
            if (allBalance.doubleValue() <= device.getMinimumConsumption().doubleValue()) {
                throw new ServiceException("用户在本运营商下余额小于最低消费金额！请充值后再试");
            }
        }

        RechargeOrder check = rechargeOrderMapper.selectByOrderCharge(user.getId());
        if (StringUtils.isNotNull(check)) {
            throw new ServiceException("存在未结束订单，请结束后再试~");
        }

        RechargeOrder rechargeOrder = new RechargeOrder();
        rechargeOrder.setPayType(1);

        if (StringUtils.isNotNull(communityMember)) {
            if(communityMember.getIsBy() == 1){
                //包月是否失效
                if(communityMember.getByTime().getTime() < System.currentTimeMillis()){
                    CommunityMember communityMember1 = new CommunityMember();
                    communityMember1.setId(communityMember.getId());
                    communityMember1.setIsBy(0);
                    communityMemberMapper.updateByPrimaryKeySelective(communityMember1);
                }
            }

            //包月钱包金额判断
            if (communityMember.getIsBy() == 1) {
                if (communityMember.getByTime().getTime() > System.currentTimeMillis()) {
                    rechargeOrder.setPayType(2);
                }
            }
            //包月判断
            else  {
                if (communityMember.getBalance().add(communityMember.getDiscountBalance()).doubleValue() <= 0) {
                    throw new ServiceException("用户余额不足！请充值后再试");
                }
                //最低消费
                if (device.getIsMinimumConsumption() == 1) {
                    if (communityMember.getBalance().add(communityMember.getDiscountBalance()).doubleValue() < device.getMinimumConsumption().doubleValue()) {
                        throw new ServiceException("用户余额小于最低消费金额！请充值后再试");
                    }
                }
            }

        }

        //握手
        //checkStatus(deviceNum);

        rechargeOrder.setPreinstallTime(Long.valueOf(chargeTime));
        rechargeOrder.setUserId(user.getId());
        rechargeOrder.setUserName(user.getNickName());
        rechargeOrder.setUserPhone(user.getPhone());
        rechargeOrder.setOperatorId(sysUser.getUserId());
        rechargeOrder.setOperatorName(sysUser.getUserName());
        rechargeOrder.setCommunityId(community.getId());
        rechargeOrder.setCommunityName(community.getCommunityName());
        rechargeOrder.setDeviceId(device.getId());
        rechargeOrder.setDeviceNum(device.getDeviceNum());
        rechargeOrder.setState(0);
        rechargeOrder.setOrderState(0);
        rechargeOrder.setOrderType(device.getBillingType());
        rechargeOrder.setHoleNum(socketNo+"");
        rechargeOrder.setOrderNum(OrderNumUtil.getOrderNum());

        rechargeOrder.setCreateTime(new Date());
        rechargeOrderMapper.insertSelective(rechargeOrder);
        //下发开门
        JSONObject jsonObject = null;
        try {
            jsonObject = ClientUtils.doGetMethod("http://localhost:8610/start/charge?orderTime=" + chargeTime
                    + "&socketNo=" + rechargeOrder.getHoleNum()
                    + "&deviceNum=" + deviceNum
                    + "&userBalance=" + communityMember.getBalance().add(communityMember.getDiscountBalance())
            );


            //log.info("充电开始传入的用户金额参数：===="+communityMember.getBalance().add(communityMember.getDiscountBalance()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (StringUtils.isNull(jsonObject) || !"200".equals(jsonObject.getString("code"))) {
            throw new ServiceException("开门失败！请稍后再试。");
        }
        return rechargeOrder.getId();
    }

    @Override
    public Long createPayRecharge(String deviceNum, BigDecimal chargeMoney, Integer socketNo) {
        User user = tokenService.getUser(ServletUtils.getRequest());
        if (user.getState() == 0) {
            throw new ServiceException("您已被禁用！");
        }
        Device device = deviceMapper.selectByNum(deviceNum);
        if (StringUtils.isNull(device)) {
            throw new ServiceException("设备不存在！");
        }
        if (device.getDeviceState() == 0) {
            throw new ServiceException("设备已禁用！");
        }
        if (device.getDeviceLineState() != 1) {
            throw new ServiceException("设备不在线！");
        }
        Community community = communityMapper.selectByPrimaryKey(device.getCommunityId());
        if (StringUtils.isNull(community)) {
            throw new ServiceException("设备未绑定小区");
        }
        if (community.getCommunityState() == 0) {
            throw new ServiceException("小区已被禁用!");
        }

        DeviceSpace deviceSpace = deviceSpaceMapper.selectBySpaceId(device.getId(), socketNo);
        if (deviceSpace.getState() != 0) {
            throw new ServiceException("插座忙碌中或故障");
        }
        SysUser sysUser = sysUserMapper.selectUserById(device.getOperatorId());
        if (StringUtils.isNull(sysUser)) {
            throw new ServiceException("设备未绑定运营商");
        }

        DeptWxInfo deptWxInfo = deptWxInfoMapper.selectByAppId(community.getAppId());
        if (deptWxInfo == null || !deptWxInfo.getAppId().equals(user.getAppId())) {
            throw new ServiceException("您无法在此设备充电！");
        }

        RechargeOrder check = rechargeOrderMapper.selectByOrderCharge(user.getId());
        if (StringUtils.isNotNull(check)) {
            throw new ServiceException("存在未结束订单，请结束后再试~");
        }
        RechargeOrder rechargeOrder = new RechargeOrder();
        rechargeOrder.setPayType(4);

        //创建支付订单
        Order order = createOrder(device.getCommunityId(), 4,chargeMoney);

        rechargeOrder.setPreinstallTime(0L);
        rechargeOrder.setPreinstallMoney(chargeMoney);
        rechargeOrder.setUserId(user.getId());
        rechargeOrder.setUserName(user.getNickName());
        rechargeOrder.setUserPhone(user.getPhone());
        rechargeOrder.setOperatorId(sysUser.getUserId());
        rechargeOrder.setOperatorName(sysUser.getUserName());
        rechargeOrder.setCommunityId(community.getId());
        rechargeOrder.setCommunityName(community.getCommunityName());
        rechargeOrder.setDeviceId(device.getId());
        rechargeOrder.setDeviceNum(device.getDeviceNum());
        rechargeOrder.setState(0);
        rechargeOrder.setOrderState(1);
        rechargeOrder.setOrderType(device.getBillingType());
        rechargeOrder.setHoleNum(socketNo.toString());
        rechargeOrder.setOrderNum(order.getOrderNo());

        rechargeOrder.setCreateTime(new Date());
        rechargeOrderMapper.insertSelective(rechargeOrder);


        return rechargeOrder.getId();
    }

    @Override
    public void delRecharge(Long orderId) {
        rechargeOrderMapper.deleteByPrimaryKey(orderId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void endRecharge(String orderNo) {
        RechargeOrder rechargeOrder = rechargeOrderMapper.selectByOrderNo(orderNo);
        if (rechargeOrder.getState() != 1) {
            throw new ServiceException("当前订单未在充电中！");
        }
        JSONObject jsonObject = null;
        try {
            jsonObject = ClientUtils.doGetMethod("http://localhost:8610/end/charge?deviceNum=" + rechargeOrder.getDeviceNum()+"&socketNo="+rechargeOrder.getHoleNum());
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (StringUtils.isNull(jsonObject) || !"200".equals(jsonObject.getString("code"))) {
            throw new ServiceException("结束失败！请稍后再试。");
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void openDoorCellOut(String orderNo) {
        /**
        User user = tokenService.getUser(ServletUtils.getRequest());
        RechargeOrder rechargeOrder = rechargeOrderMapper.selectByOrderNo(orderNo);
        rechargeOrder.setAllMoney(rechargeOrder.getRechargeMoney());
        //握手
        checkStatus(rechargeOrder.getDeviceNum());

        CommunityMember communityMember = communityMemberMapper.selectByUser(user.getId(), rechargeOrder.getCommunityId());
        //余额通用
        if (StringUtils.isNull(communityMember)) {
            BigDecimal balance = communityMemberMapper.getBalanceByOperatorId(user.getId(), rechargeOrder.getOperatorId());
            //扣款
            BigDecimal orderMoney = rechargeOrder.getAllMoney();
            BigDecimal countMoney = orderMoney;
            if (balance.doubleValue() < orderMoney.doubleValue()) {
                throw new ServiceException("本运营商下余额不足！请充值后开门！");
            }
            List<CommunityMember> communityMembers = communityMemberMapper.getCommunityMembersByOperatorId(user.getId(), rechargeOrder.getOperatorId());
            for (CommunityMember communityMember1 : communityMembers) {

                if (countMoney.doubleValue() > communityMember1.getBalance().doubleValue()) {
                    countMoney = countMoney.subtract(communityMember1.getBalance());
                    communityMember1.setBalance(new BigDecimal("0"));
                    System.out.println("金额大于余额");
                    System.out.println(communityMember1.getBalance());
                    System.out.println(communityMember1.getDiscountBalance());
                    System.out.println(countMoney);
                } else if (countMoney.doubleValue() < communityMember1.getBalance().doubleValue()) {
                    communityMember1.setBalance(communityMember1.getBalance().subtract(countMoney));
                    countMoney = BigDecimal.valueOf(0);
                    System.out.println("金额小于余额");
                    System.out.println(communityMember1.getBalance());
                    System.out.println(communityMember1.getDiscountBalance());
                    System.out.println(countMoney);
                }
                if (countMoney.doubleValue() > communityMember1.getDiscountBalance().doubleValue()) {
                    countMoney = countMoney.subtract(communityMember1.getDiscountBalance());
                    communityMember1.setDiscountBalance(new BigDecimal("0"));
                    System.out.println("金额大于活动余额");
                    System.out.println(communityMember1.getBalance());
                    System.out.println(communityMember1.getDiscountBalance());
                    System.out.println(countMoney);
                } else if (countMoney.doubleValue() < communityMember1.getDiscountBalance().doubleValue()) {
                    communityMember1.setDiscountBalance(communityMember1.getDiscountBalance().subtract(countMoney));
                    countMoney = BigDecimal.valueOf(0);
                    System.out.println("金额小于活动余额");
                    System.out.println(communityMember1.getBalance());
                    System.out.println(communityMember1.getDiscountBalance());
                    System.out.println(countMoney);
                }
                communityMemberMapper.updateByPrimaryKeySelective(communityMember1);
                if (countMoney.doubleValue() == 0D) {
                    break;
                }
            }
            if (countMoney.doubleValue() > 0) {
                throw new ServiceException("本运营商下余额不足！扣款失败！请充值后开门！");
            }
        }
        //不是集团
        if (StringUtils.isNotNull(communityMember) && communityMember.getIsBloc() == 0) {
            //余额
            if (rechargeOrder.getPayType() == 1) {
                //扣款
                BigDecimal orderMoney = rechargeOrder.getAllMoney();
                if (orderMoney.doubleValue() < communityMember.getDiscountBalance().doubleValue()) {
                    communityMember.setDiscountBalance(communityMember.getDiscountBalance().subtract(orderMoney));
                } else if (orderMoney.doubleValue() < communityMember.getBalance().doubleValue()) {
                    communityMember.setBalance(communityMember.getBalance().subtract(orderMoney));
                } else if (orderMoney.doubleValue() < communityMember.getDiscountBalance().add(communityMember.getBalance()).doubleValue()) {
                    communityMember.setBalance(communityMember.getBalance().add(orderMoney));
                    communityMember.setDiscountBalance(communityMember.getBalance().add(communityMember.getDiscountBalance()));
                    communityMember.setBalance(new BigDecimal("0"));
                } else {
                    throw new ServiceException("余额不足！请充值后开门！");
                }
                communityMemberMapper.updateByPrimaryKeySelective(communityMember);
            }
            //电卡
            else if (rechargeOrder.getPayType() == 3) {
                Card card = cardMapper.selectByNum(rechargeOrder.getCardNo());
                //扣款
                BigDecimal orderMoney = rechargeOrder.getAllMoney();
                if (orderMoney.doubleValue() < card.getDiscountsMoney().doubleValue()) {
                    card.setDiscountsMoney(card.getDiscountsMoney().subtract(orderMoney));
                } else if (orderMoney.doubleValue() < card.getMoney().doubleValue()) {
                    card.setMoney(card.getMoney().subtract(orderMoney));
                } else if (orderMoney.doubleValue() < card.getDiscountsMoney().add(card.getMoney()).doubleValue()) {
                    card.setMoney(card.getMoney().subtract(orderMoney));
                    card.setDiscountsMoney(card.getDiscountsMoney().add(card.getMoney()));
                    card.setMoney(new BigDecimal("0"));
                } else {
                    throw new ServiceException("余额不足！请充值后开门！");
                }
                cardMapper.updateByPrimaryKeySelective(card);
            }


        }

        //下发开门
        JSONObject jsonObject = null;
        try {
            jsonObject = ClientUtils.doGetMethod("http://localhost:8610/end/charge?orderNo=" + rechargeOrder.getOrderNum());
            log.info(jsonObject.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (StringUtils.isNull(jsonObject) || !"200".equals(jsonObject.getString("code"))) {
            throw new ServiceException("开门失败！请稍后再试。");
        }
        */
    }



    private void checkStatus(String deviceNum) {
        log.info("握手开始");
        int msgId = Integer.parseInt(OrderNumUtil.getRandom());
        log.info(msgId+"");
        //加锁asd
        mqttLockUtil.lock(msgId + "");
        try {
            JSONObject jsonObject = ClientUtils.doGetMethod("http://localhost:8610/check?deviceNum=" + deviceNum + "&msgId=" + msgId);
            log.info(jsonObject.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException("设备无响应,请稍后再试!");
        }
        if (!mqttLockUtil.checkLock(msgId + "", 10)) {
            throw new ServiceException("设备无响应!");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long createChargeOrder(Long communityId, Long optionId) {
        Order order = createOrder(communityId, 1);
        ChargeOption chargeOption = chargeOptionMapper.selectByPrimaryKey(optionId);
        BigDecimal chargeMoney = chargeOption.getMoney();
        OrderCharge orderCharge = new OrderCharge();
        orderCharge.setOrderId(order.getId());
        orderCharge.setChargeMoney(chargeOption.getMoney());
        orderCharge.setDiscountMoney(chargeOption.getDiscountsMoney());
        orderChargeMapper.insertSelective(orderCharge);
        order.setMoney(chargeMoney);
        orderMapper.updateByPrimaryKeySelective(order);
        return order.getId();
    }

    Order createOrder(Long communityId, Integer type) {
        User user = userMapper.selectByPrimaryKey(tokenService.getUser(ServletUtils.getRequest()).getId());
        Community community = communityMapper.selectByPrimaryKey(communityId);
        if (StringUtils.isNull(community)) {
            throw new ServiceException("小区不存在!");
        }
        if (community.getCommunityType() == 2) {
            throw new ServiceException("集团内部设备，暂不对外开放。");
        }
        Order order = new Order();
        order.setUserId(user.getId());
        order.setUserName(user.getUsername());


        order.setUserPhone(user.getPhone());
        order.setCommunityId(community.getId());
        order.setCommunityName(community.getCommunityName());
        order.setOperatorId(community.getOperatorId());
        order.setOperatorName(community.getOperatorName());
        order.setOrderNo(OrderNumUtil.getOrderNum());
        order.setOrderType(type);
        order.setOrderState(0);
        order.setCreateTime(new Date());
        orderMapper.insertSelective(order);
        return order;
    }

    //临时充电创建订单
    Order createOrder(Long communityId, Integer type,BigDecimal money) {
        User user = userMapper.selectByPrimaryKey(tokenService.getUser(ServletUtils.getRequest()).getId());
        Community community = communityMapper.selectByPrimaryKey(communityId);
        if (StringUtils.isNull(community)) {
            throw new ServiceException("小区不存在!");
        }
        if (community.getCommunityType() == 2) {
            throw new ServiceException("集团内部设备，暂不对外开放。");
        }
        Order order = new Order();
        order.setUserId(user.getId());
        order.setUserName(user.getUsername());

        order.setUserPhone(user.getPhone());
        order.setCommunityId(community.getId());
        order.setCommunityName(community.getCommunityName());
        order.setOperatorId(community.getOperatorId());
        order.setOperatorName(community.getOperatorName());
        order.setOrderNo(OrderNumUtil.getOrderNum());
        order.setOrderType(type);
        order.setOrderState(0);
        order.setMoney(money);
        order.setCreateTime(new Date());
        orderMapper.insertSelective(order);
        return order;
    }

    @Override
    public Map createWxPayV2(Long orderId, Integer type, String code, String appId) {
        DeptWxInfo deptWxInfo = deptWxInfoMapper.selectByAppId(appId);
        String openId = getOpenId(code, deptWxInfo.getAppId(), deptWxInfo.getAppSecret());

        if (type != 4) {
            Order order = orderMapper.selectByPrimaryKey(orderId);
            if (order.getMoney().doubleValue() <= 0) {
                throw new ServiceException("金额异常");
            }
            return getWxPayValue(deptWxInfo, order.getOrderNo(), order.getMoney(), openId, type + ":" + deptWxInfo.getDeptId(),  "钱包充值" );
        }else {
            RechargeOrder rechargeOrder = rechargeOrderMapper.selectByPrimaryKey(orderId);
            if (rechargeOrder.getPreinstallMoney().doubleValue() <= 0) {
                throw new ServiceException("金额异常");
            }
            return getWxPayValue(deptWxInfo, rechargeOrder.getOrderNum(), rechargeOrder.getPreinstallMoney(), openId, type + ":" + deptWxInfo.getDeptId(),  "临时充电");
        }

    }

    //加入小区
    private CommunityMember checkCommunityMember(CommunityMember communityMember, User user, Long communityId) {

        if (StringUtils.isNull(communityMember)) {
            log.info("构建 new ");
            Community community = communityMapper.selectByPrimaryKey(communityId);
            communityMember = new CommunityMember();
            communityMember.setCommunityId(community.getId());
            communityMember.setCommunityName(community.getCommunityName());
            communityMember.setUserId(user.getId());
            communityMember.setUserName(user.getUsername());
            communityMember.setCreateTime(new Date());
            communityMemberMapper.insertSelective(communityMember);
            return communityMemberMapper.selectByPrimaryKey(communityMember.getId());
        }
        return communityMember;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void wxPayResult(Map<String, String> mapResult, String attach) {


        //钱包余额充值
        if ("1".equals(attach)) {
            Order order = orderMapper.selectByNo(mapResult.get("out_trade_no"));
            User user = userMapper.selectByPrimaryKey(order.getUserId());
            order.setWxOrderNo(mapResult.get("transaction_id"));
            order.setOrderState(1);
            OrderCharge orderCharge = orderChargeMapper.selectByPrimaryKey(order.getId());
            orderCharge.setChargeTime(new Date());
            CommunityMember communityMember1 = communityMemberMapper.selectByUser(user.getId(), order.getCommunityId());
            checkCommunityMember(communityMember1, user, order.getCommunityId());
            CommunityMember communityMember = communityMemberMapper.selectByUser(user.getId(), order.getCommunityId());

            orderCharge.setBeforeMoney(communityMember.getBalance().add(communityMember.getDiscountBalance()));
            communityMember.setBalance(communityMember.getBalance().add(orderCharge.getChargeMoney()));
            communityMember.setDiscountBalance(communityMember.getDiscountBalance().add(orderCharge.getDiscountMoney()));
            orderCharge.setAfterMoney(communityMember.getBalance().add(communityMember.getDiscountBalance()));

            //分成
            orderParticipation(order, 0);
            orderChargeMapper.updateByPrimaryKeySelective(orderCharge);
            orderMapper.updateByPrimaryKeySelective(order);
            communityMemberMapper.updateByPrimaryKeySelective(communityMember);
        }
        //包月会员充值
        else if ("2".equals(attach)) {
            Order order = orderMapper.selectByNo(mapResult.get("out_trade_no"));
            User user = userMapper.selectByPrimaryKey(order.getUserId());
            order.setWxOrderNo(mapResult.get("transaction_id"));
            order.setOrderState(1);
            OrderCombo orderCombo = orderComboMapper.selectByPrimaryKey(order.getId());
            orderCombo.setChargeTime(new Date());

            CommunityMember communityMember = communityMemberMapper.selectByUser(user.getId(), order.getCommunityId());
            communityMember = checkCommunityMember(communityMember, user, order.getCommunityId());

            if (communityMember.getIsBy() == 1) {
                if (communityMember.getByTime().getTime() > System.currentTimeMillis()) {
                    communityMember.setByTime(DateUtils.addDays(communityMember.getByTime(), orderCombo.getComboTime()));
                } else {
                    communityMember.setByTime(DateUtils.addDays(new Date(), orderCombo.getComboTime()));
                }
            } else {
                communityMember.setIsBy(1);
                communityMember.setByTime(DateUtils.addDays(new Date(), orderCombo.getComboTime()));
            }
            orderCombo.setExpireTime(communityMember.getByTime());
            //分成
            orderParticipation(order, 1);
            orderComboMapper.updateByPrimaryKeySelective(orderCombo);
            orderMapper.updateByPrimaryKeySelective(order);
            communityMemberMapper.updateByPrimaryKeySelective(communityMember);
        }
        //电卡充值
        else if ("3".equals(attach)) {
            Order order = orderMapper.selectByNo(mapResult.get("out_trade_no"));
            order.setWxOrderNo(mapResult.get("transaction_id"));
            order.setOrderState(1);
            OrderCardCharge orderCardCharge = orderCardChargeMapper.selectByPrimaryKey(order.getId());
            orderCardCharge.setChargeTime(new Date());
            Card card = cardMapper.selectByNum(orderCardCharge.getCardNum());

            orderCardCharge.setBeforeMoney(card.getMoney().add(card.getDiscountsMoney()));

            card.setMoney(card.getMoney().add(orderCardCharge.getChargeMoney()));
            card.setDiscountsMoney(card.getDiscountsMoney().add(orderCardCharge.getDiscountMoney()));

            orderCardCharge.setAfterMoney(card.getMoney().add(card.getDiscountsMoney()));

            //分成
            orderParticipation(order, 2);
            orderCardChargeMapper.updateByPrimaryKeySelective(orderCardCharge);
            orderMapper.updateByPrimaryKeySelective(order);
            cardMapper.updateByPrimaryKeySelective(card);
        }
        //临时充电
        else if ("4".equals(attach)) {
            Order order = orderMapper.selectByNo(mapResult.get("out_trade_no"));

            order.setWxOrderNo(mapResult.get("transaction_id"));
            order.setOrderState(1);
            RechargeOrder rechargeOrder = rechargeOrderMapper.selectByOrderNo(mapResult.get("out_trade_no"));
            rechargeOrder.setPayNum(mapResult.get("transaction_id"));
            rechargeOrder.setOrderState(1);

            //下发充电
            JSONObject jsonObject = null;
            try {
                jsonObject = ClientUtils.doGetMethod("http://localhost:8610/start/pay/charge?orderMoney=" + rechargeOrder.getPreinstallMoney()
                        + "&deviceNum=" + rechargeOrder.getDeviceNum()
                        + "&socketNo=" + rechargeOrder.getHoleNum()
                );
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (StringUtils.isNull(jsonObject) || !"200".equals(jsonObject.getString("code"))) {
                log.info("临时支付充电失败！订单号：" + rechargeOrder.getOrderNum());
            }

            //分成
            orderParticipation(order, 5);
            orderMapper.updateByPrimaryKeySelective(order);


        }

    }

    private void orderParticipation(Order order, Integer type) {
        SysUser sysUser = sysUserMapper.selectUserById(order.getOperatorId());
        List<CommunityPartner> communityPartners = communityPartnerMapper.getListByCommunityId(order.getCommunityId());
        BigDecimal proportionMoney = order.getMoney();
        if (communityPartners.size() > 0) {
            for (CommunityPartner communityPartner : communityPartners) {
                SysUser partner = sysUserMapper.selectUserById(communityPartner.getUserId());
                BigDecimal partnerMoney = proportionMoney.multiply(BigDecimal.valueOf(communityPartner.getRatio()));
                BigDecimal partnerService = partnerMoney.multiply(partner.getServiceMoney());
                partnerMoney = partnerMoney.subtract(partnerService);
                log.info("分账人：{}.分成金额:{},手续费：{}", partner.getUserName(), partnerMoney, partnerService);
                proportionMoney = proportionMoney.subtract(partnerMoney.add(partnerService));
                partner.setBalance(partner.getBalance().add(partnerMoney));
                addParticipation(partner.getUserId(), order, partnerMoney, partnerService, type, partner.getWithdrawTime());
                sysUserMapper.updateUser(partner);

            }
        }

        BigDecimal operatorService = proportionMoney.multiply(sysUser.getServiceMoney());
        proportionMoney = proportionMoney.subtract(operatorService);
        sysUser.setBalance(sysUser.getBalance().add(proportionMoney));
        addParticipation(sysUser.getUserId(), order, proportionMoney, operatorService, type, sysUser.getWithdrawTime());
        sysUserMapper.updateUser(sysUser);
        log.info("运营商：{}.分成金额:{},手续费：{}", sysUser.getUserName(), proportionMoney, operatorService);
    }

    private void addParticipation(Long sysId, Order order, BigDecimal partnerMoney, BigDecimal partnerService, Integer type, Integer time) {
        Participation participation = new Participation();
        participation.setOrderId(order.getId());
        participation.setOrderNum(order.getOrderNo());
        participation.setType(type);
        participation.setParticipationState(0);
        participation.setSysId(sysId);
        participation.setMoney(partnerMoney);
        participation.setServiceMoney(partnerService);
        participation.setCreateTime(new Date());
        participation.setParticipationTime(DateUtils.addDays(new Date(), time));
        participation.setRemark("用户:"+order.getUserPhone()+" 充值了"+order.getMoney()+"元");
        participationMapper.insertSelective(participation);

    }

    /**
     * 微信支付处理
     *
     * @param orderNum 订单id
     * @param money    订单金额
     * @return
     */
    public Map getWxPayValue(DeptWxInfo deptWxInfo, String orderNum, BigDecimal money, String openId, String attach, String body) {
        Map param = new HashMap();
        param.put("appid", deptWxInfo.getAppId());//公众账号ID
        param.put("mch_id", deptWxInfo.getMchId());//商户
        param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串

        param.put("attach", attach);
        param.put("body", body);
        param.put("out_trade_no", orderNum);//交易订单号
        param.put("total_fee", money.multiply(new BigDecimal("100")).stripTrailingZeros().toPlainString());//金额（分）

        param.put("spbill_create_ip", "127.0.0.1");//终端ip
        param.put("notify_url", wxPledgeConfig.getNOTIFY_URL());//通知地址
        param.put("trade_type", "JSAPI");//交易类型
        param.put("openid", openId);
        try {
            String xmlParam = WXPayUtil.generateSignedXml(param, deptWxInfo.getWxKey());

            //2.发送请求
            String xmlResult = ClientUtils.doPostMethod("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlParam, "utf-8", null);
            //3.获取结果
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            Map<String, String> repData = new LinkedHashMap<>();
            repData.put("appId", deptWxInfo.getAppId());
            repData.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
            repData.put("nonceStr", mapResult.get("nonce_str"));
            repData.put("package", "prepay_id=" + mapResult.get("prepay_id"));

            repData.put("signType", "MD5");
            System.out.println(xmlParam);
            System.out.println(repData);
            System.out.println(deptWxInfo.getWxKey());
            String sign = WXPayUtil.generateSignature(repData, deptWxInfo.getWxKey()); //签名
            System.out.println("生成签名:" + sign);
            repData.put("paySign", sign);
            return repData;
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getOpenId(String code, String appId, String appSecret) {
        String path = wxPledgeConfig.getPHONE_URL()
                + "appid="
                + appId
                + "&secret="
                + appSecret
                + "&js_code="
                + code
                + "&grant_type=authorization_code";
        try {
            // 向微信服务器发送get请求获取加密了的内容
            JSONObject jsonObject = ClientUtils.doGetMethod(path);
            return jsonObject.getString("openid");
        } catch (Exception e) {
            log.error("微信小程序手机号码解密异常，信息如下:", e);
        }
        return null;
    }


    /**
     * 微信 服务商创建预支付 支付处理
     *
     * @param orderNum 订单id
     * @param money    订单金额
     * @return
     */
    public Map getWxPayValue(String orderNum, BigDecimal money, String openId, String attach, String body) {

        Map param = new HashMap();
        param.put("appid", "服务商appid");//公众账号ID
        param.put("mch_id", "服务商商户号");//商户
        param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串

        param.put("attach", attach);
        param.put("body", body);
        param.put("out_trade_no", orderNum);//交易订单号
        param.put("total_fee", money.multiply(new BigDecimal("100")).stripTrailingZeros().toPlainString());//金额（分）

        param.put("sub_mch_id","下属商户号");//下属商户号
        param.put("sub_appid", "下属appid");

        param.put("spbill_create_ip", "127.0.0.1");//终端ip
        param.put("notify_url", "");//通知地址
        param.put("trade_type", "JSAPI");//交易类型
        param.put("sub_openid", openId);
        try {
            String xmlParam = WXPayUtil.generateSignedXml(param, "密钥");

            //2.发送请求
            String xmlResult = ClientUtils.doPostMethod("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlParam, "utf-8",null);
            //3.获取结果
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            Map<String, String> repData = new LinkedHashMap<>();
            repData.put("appId", "下属appid");
            repData.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
            repData.put("nonceStr", mapResult.get("nonce_str"));
            repData.put("package", "prepay_id=" + mapResult.get("prepay_id"));

            repData.put("signType", "MD5");
            System.out.println(xmlParam);
            System.out.println(mapResult);
            System.out.println(repData);
            String sign = WXPayUtil.generateSignature(repData, "密钥"); //签名
            //System.out.println("生成签名:" + sign);
            repData.put("paySign", sign);
            return repData;
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
